package core.game_states;

import java.util.Vector;

import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.state.StateBasedGame;


import core.SpriteVault;
import core.entities.Projectile;
import core.entities.objects.towers.Tower;
import core.entities.objects.towers.TowerTest;
import core.levels.Level;
import core.levels.LevelTest;

public class StateBattle extends GameState
{
	static final int MX = 16, MY = 8; //map size (32;16)
	static final int DECK_SIZE = 8;
	private Input in;
	private Level level;
	private Tower deckTowers[] = new Tower[DECK_SIZE];
	private Tower mapTowers[][] = new Tower[MY][MX];
	private Tower curBuildTower = null;
	
	Vector<Projectile> projectiles = new Vector<Projectile>();
	
	public StateBattle()
	{
		
	}

	@Override
	public void init(GameContainer gc, StateBasedGame sbg)
			throws SlickException
	{
		SX = gc.getWidth();
		SY = gc.getHeight();
		level = new LevelTest("field");	
		
		in = gc.getInput();
		//Load Sprites
		SpriteVault.loadSprites();
		
		deckTowers[0] = new TowerTest(600, 632);
		
		for(int i=0; i<MY; ++i)
		{
			for(int j=0; j<MX; ++j)
			{
				mapTowers[i][j] = null;
			}
		}
		
		//tower = new Entity(450, 500, 32, 32, SpriteVault.getSprite(0));
	}

	@Override
	public void render(GameContainer gc, StateBasedGame sbg, Graphics g)
			throws SlickException
	{
		// + Rendering playing area	
		g.setClip(0, 88, 1024, 512);
		level.render();
		
		// + Towers
		for(int i=0; i<MY; ++i)
		{
			for(int j=0; j<MX; ++j)
			{
				if(mapTowers[i][j] != null)
				{
					mapTowers[i][j].render(g);
				}
			}
		}
		// - Towers
		
		// + Tower Building Template
		if(curBuildTower != null && in.getMouseY() > 88 && in.getMouseY()<600)
		{
			int x = in.getMouseX()/64, y = (in.getMouseY() - 88) / 64;
			Color color;
			if(mapTowers[y][x]==null)
				color = new Color(100, 255, 100 ,180);
			else 
				color = new Color(255, 100, 100 ,180);
			g.setColor(new Color(0,0,0,32));
			g.drawOval(x * 64 - curBuildTower.getRadius() + 32  ,  y * 64 + 120 - curBuildTower.getRadius(),
					curBuildTower.getRadius()*2, curBuildTower.getRadius()*2);
			g.setColor(color);
			g.fillOval(x * 64 - curBuildTower.getRadius() + 32 ,  y * 64 + 120 - curBuildTower.getRadius(),
					curBuildTower.getRadius()*2, curBuildTower.getRadius()*2);
			g.drawImage(curBuildTower.getSprite().getScaledCopy(2.0f),
					x * 64,  y * 64 + 88, color);
		}
		// - Tower Building Template
		
		// + Projectiles
		for(int i = 0; i < projectiles.size(); ++i)
		{
			projectiles.get(i).render(g);
		}
		// - Projectiles
		
		
		g.clearClip();
		// - Rendering playing area
		
		// + rendering GUI
		
		// + tower list
		for(int i=0; i<DECK_SIZE; ++i)
		{
			g.drawImage(SpriteVault.getSprite(1).getScaledCopy( 1.5f ), 600+i*49, 632);
			g.drawImage(SpriteVault.getSprite(2).getScaledCopy( 1.5f ), 600+i*49, 692);
			if(deckTowers[i]!=null)
				deckTowers[i].render(g, 1.5f);
		}
		// - tower list
		
		// - rendering GUI
		
	}

	@Override
	public void update(GameContainer gc, StateBasedGame sbg, int delta)
			throws SlickException
	{
		if (in.isMousePressed(Input.MOUSE_LEFT_BUTTON))
		{
			if( in.getMouseY() > 88 && in.getMouseY()<600)
			{
				if(in.isKeyDown(Input.KEY_LSHIFT) && curBuildTower == null)
					shoot();
				else if(curBuildTower != null)
					buildTower( in.getMouseX() / 64, (in.getMouseY() - 88) / 64 );
			}
			else if(in.getMouseY() > 632 && in.getMouseY()<692 && in.getMouseX()>600 && in.getMouseX()<992)
			{
				curBuildTower = deckTowers[ (in.getMouseX() - 600) / 49 ];
			}
		}
		else if(in.isMousePressed(Input.MOUSE_RIGHT_BUTTON))
		{
			curBuildTower = null;
		}
		
		
		// + Projectiles
		for(int i = 0; i < projectiles.size(); ++i)
		{
			if(projectiles.get(i).isOutBound())
			{
				projectiles.remove(i);
				--i;
				continue;
			}
			projectiles.get(i).update(delta);
		}
		// - Projectiles
	}

	@Override
	public int getID()
	{
		
		return 1;
	}
	
	private void shoot()
	{
		int startY = 258;
		double angle =  Math.toDegrees(Math.atan2(in.getMouseX(), in.getMouseY() - startY)) - 90;
		projectiles.add(new Projectile(0, startY, 
				SpriteVault.getSprite(3).getScaledCopy(1.5f), (float)angle));
	}

	private void buildTower(int x, int y)
	{
		if(mapTowers[y][x]==null)
		{
			mapTowers[y][x] = new Tower(curBuildTower);
			mapTowers[y][x].setSprite(curBuildTower.getSprite().getScaledCopy(2.0f));
			mapTowers[y][x].setX(x * 64);
			mapTowers[y][x].setY(y * 64 +88);		
			if(!in.isKeyDown(Input.KEY_LCONTROL))
				curBuildTower=null;
		}
	}
}
